﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EnvDTE;
using Microsoft.SqlServer.Management.UI.VSIntegration;
using Microsoft.Data.Schema.ScriptDom.Sql;
using Microsoft.Data.Schema.ScriptDom;
using System.IO;
using EnvDTE80;

namespace SSMSAddinDenali
{
    /// <summary>
    /// Format SQL Statement Class
    /// </summary>
    public static class FormatSQLStatement
    {
        /// <summary>
        /// Format SQL in a Window
        /// </summary>
        /// <param name="application"></param>
        public static void FormatSQLWindow(DTE2 application)
        {
            EnvDTE.TextDocument doc = (EnvDTE.TextDocument)ServiceCache.ExtensibilityModel.Application.ActiveDocument.Object(null);

            if (doc != null)
            {
                string SQLToFormat = DTEApplicationHelper.GetSQLString(doc);

                if (SQLToFormat.Length > 0)
                {
                    string formattedSQL = Format(SQLToFormat, application);

                    doc.ReplaceText(SQLToFormat, formattedSQL, 0);
                }
            }
        }

        /// <summary>
        /// Format SQL Statments
        /// </summary>
        /// <param name="SQL"></param>
        /// <param name="application"></param>
        /// <returns></returns>
        private static string Format(string SQL, DTE2 application)
        {
            string formattedSQL = SQL;

            TSql100Parser _parser = new TSql100Parser(true);
            Sql100ScriptGenerator _scriptGen;

            SqlScriptGeneratorOptions options = new SqlScriptGeneratorOptions();

            options.SqlVersion = SqlVersion.Sql100;
            options.KeywordCasing = KeywordCasing.Uppercase;

            _scriptGen = new Sql100ScriptGenerator(options);

            string inputScript = SQL;
            IScriptFragment fragment;
            IList<ParseError> errors;
            using (StringReader sr = new StringReader(inputScript))
            {
                fragment = _parser.Parse(sr, out errors);
            }
            if (errors != null && errors.Count > 0)
            {
                StringBuilder sb = new StringBuilder();
                foreach (var error in errors)
                {
                    sb.AppendLine(error.Message);
                    sb.AppendLine("offset " + error.Offset.ToString());
                }
                DTEApplicationHelper.WriteToOutputWindow(application, sb.ToString());
            }
            else
            {
                String script;
                _scriptGen.GenerateScript(fragment, out script);
                formattedSQL = script;
            }

            return formattedSQL;
        }
    }
}
